#ifndef laser_H
#define laser_H

#include "../sprite_handler.h"
#include "../input.h"
#include "../scrolling.h"


// turret Data
typedef struct STRUCT_LASER_DATA
{	
	int map_position_x, map_position_y;
	int dir_x, dir_y;
	int wait_before_move_x;
	int wait_before_move_y;
	int milliseconds_since_last_horizontal_move, milliseconds_since_last_vertical_move;
	
	CharacterType owner;
	
} LaserData;


////////////////////////////////////////////////////////////
// function prototypes
////////////////////////////////////////////////////////////
void laserInit(SpriteHandler *, int, int, CharacterType, int);
void laserUpdateFunction(SpriteHandler *);
int GetLaserSize(int);
int GetLaserFrameIndex(int);
int GetDirX(SpriteHandler *);
int GetDirY(SpriteHandler *);


////////////////////////////////////////////////////////////
// Function: playerInit
// ...
////////////////////////////////////////////////////////////
void laserInit(SpriteHandler * sprite_handler, int wait_before_move_x, int wait_before_move_y, CharacterType charType, int laser_level)
{
    // create new sprite handler for turret
	SpriteHandler * laser = newSpriteHandler();
	
	laser->characterType = CHAR_LASER;
	
	// Set userdata
	LaserData * laser_data = malloc( sizeof( LaserData ) );	
	memset( laser_data, 0, sizeof( LaserData ) ); // Zero set the userdata
	
	laser->userData = laser_data; // Set the user data
    
    int char_screen_pos_x = sprite_handler->x;
    int char_screen_pos_y = sprite_handler->y;
    
    int char_map_pos_x = starsBG.x + char_screen_pos_x;
    int char_map_pos_y = starsBG.y + char_screen_pos_y;
    
    int char_width = GetSpriteWidth(sprite_handler);
    int char_height = GetSpriteHeight(sprite_handler);
	
	laser->_imageIndex = GetLaserFrameIndex(laser_level);
	laser->size = SD_8x8;
	
	laser_data->map_position_x = char_map_pos_x + (char_width >> 1) - (GetLaserSize(laser_level) >> 1);
	laser_data->map_position_y = char_map_pos_y + (char_height >> 1) - (GetLaserSize(laser_level) >> 1);
	
	laser_data->dir_x = GetDirX(sprite_handler);
	laser_data->dir_y = GetDirY(sprite_handler);
	
	// TODO: look into a universal way to get & set these wait x & y values for all sprites
	laser_data->wait_before_move_x = wait_before_move_x;
	laser_data->wait_before_move_y = wait_before_move_y;
	
	laser_data->owner = charType;
	
	laser_data->milliseconds_since_last_horizontal_move = wait_before_move_x + 1;
	laser_data->milliseconds_since_last_vertical_move = wait_before_move_y + 1;
	
	updateSpriteAttributes( laser );
}


////////////////////////////////////////////////////////////
// Function: playerInit
// ...
////////////////////////////////////////////////////////////
void laserUpdateFunction( SpriteHandler * sprite_handler )
{
	if ( sprite_handler->userData == NULL ) { return; }
	
	LaserData * laser_data = sprite_handler->userData;

    laser_data->milliseconds_since_last_horizontal_move += getElapsedTime();
    laser_data->milliseconds_since_last_vertical_move += getElapsedTime();
    
    // update laser's x position
    if (laser_data->milliseconds_since_last_horizontal_move > laser_data->wait_before_move_x) {
        laser_data->milliseconds_since_last_horizontal_move = 0;
        laser_data->map_position_x = (laser_data->map_position_x + laser_data->dir_x);
    }
    
    // update laser's y position
    if (laser_data->milliseconds_since_last_vertical_move > laser_data->wait_before_move_y) {
        laser_data->milliseconds_since_last_vertical_move = 0;
        laser_data->map_position_y = (laser_data->map_position_y + laser_data->dir_y);
    }
    
    // check if laser has exited the screen
    if (laser_data->map_position_x > starsBG.x + SCREEN_WIDTH ||
        laser_data->map_position_x < starsBG.x ||
        laser_data->map_position_y > starsBG.y + SCREEN_HEIGHT ||
        laser_data->map_position_y < starsBG.y)
    {
        sprite_handler->alive = FALSE;
    }
	
	// Update the Sprite Attributes to reflect the changes we make in sprite_handler
	updateSpriteAttributes( sprite_handler );
}


////////////////////////////////////////////////////////////
// Function: playerInit
// ...
////////////////////////////////////////////////////////////
int GetLaserSize(int level)
{
    switch(level) {
        case 1: return 3; break;
        case 2: return 4; break;
        case 3: return 5; break;
        case 4: return 6; break;
        default: return 3;
    }
    
    return 2;
}


////////////////////////////////////////////////////////////
// Function: playerInit
// ...
////////////////////////////////////////////////////////////
int GetLaserFrameIndex(int level)
{
    switch(level) {
        case 1: return FRAME_LASER_LEVEL_1; break;
        case 2: return FRAME_LASER_LEVEL_2; break;
        case 3: return FRAME_LASER_LEVEL_3; break;
        case 4: return FRAME_LASER_LEVEL_4; break;
        default: return FRAME_LASER_LEVEL_1;
    }

    return FRAME_LASER_LEVEL_1;
}


////////////////////////////////////////////////////////////
// Function: playerInit
// ...
////////////////////////////////////////////////////////////
int GetDirX(SpriteHandler * sprite_handler)
{
    int angle = sprite_handler->angle;
    int dir_x_to_return = 0;
    
    if (angle == 0 || angle == 180) {
        dir_x_to_return = 0;
    }
    else if (angle > 0 && angle < 180) {
        dir_x_to_return = 1;
    }
    else if (angle > 180 && angle < 360) {
        dir_x_to_return = -1;
    }
    
    return dir_x_to_return;
}


////////////////////////////////////////////////////////////
// Function: playerInit
// ...
////////////////////////////////////////////////////////////
int GetDirY(SpriteHandler * sprite_handler)
{
    int angle = sprite_handler->angle;
    int dir_y_to_return = 0;

    if (angle == 90 || angle == 270) {
        dir_y_to_return = 0;
    }
    else if ((angle > 270 && angle < 360) || (angle > 0 && angle < 90) || angle == 0) {
        dir_y_to_return = -1;
    }
    else if (angle > 90 && angle < 270) {
        dir_y_to_return = 1;
    }
    
    return dir_y_to_return;
}


#endif

